Skip to main content

安裝 Terraform 環境

安裝 Terraform

terraform -help
Usage: terraform [global options] <subcommand> [args]

The available commands for execution are listed below.
The primary workflow commands are given first, followed by
less common or more advanced commands.

Main commands:
init Prepare your working directory for other commands
validate Check whether the configuration is valid
plan Show changes required by the current configuration
apply Create or update infrastructure
destroy Destroy previously-created infrastructure

All other commands:
console Try Terraform expressions at an interactive command prompt
fmt Reformat your configuration in the standard style
force-unlock Release a stuck lock on the current workspace
get Install or upgrade remote Terraform modules
graph Generate a Graphviz graph of the steps in an operation
import Associate existing infrastructure with a Terraform resource
login Obtain and save credentials for a remote host
logout Remove locally-stored credentials for a remote host
metadata Metadata related commands
output Show output values from your root module
providers Show the providers required for this configuration
refresh Update the state to match remote systems
show Show the current state or a saved plan
state Advanced state management
taint Mark a resource instance as not fully functional
test Execute integration tests for Terraform modules
untaint Remove the 'tainted' state from a resource instance
version Show the current Terraform version
workspace Workspace management

Global options (use these before the subcommand, if any):
-chdir=DIR Switch to a different working directory before executing the
given subcommand.
-help Show this help output, or the help for a specified subcommand.
-version An alias for the "version" subcommand.

其他需準備環境

  1. 擁有 AWS 帳號
  2. 建立 credential 擁有建立資源的權限
  3. 安裝 AWS Command Line

自動補齊指令

啟用終端機上的 Tab 自動補齊指令功能

touch ~/.bashrc
touch ~/.zshrc
terraform -install-autocomplete

快速入門教學

  • 安裝 docker 應用程式
  • mkdir learn-terraform-docker-container
    • 建立資料夾放置 Terraform 檔案
  • cd learn-terraform-docker-container
    • 進入到該資料夾
在資料夾創建 main.tf 檔案並附加以下內容
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0.1"
}
}
}

provider "docker" {
host = "npipe:////.//pipe//docker_engine"
}

resource "docker_image" "nginx" {
name = "nginx"
keep_locally = false
}

resource "docker_container" "nginx" {
image = docker_image.nginx.image_id
name = "tutorial"

ports {
internal = 80
external = 8000
}
}
terraform apply
Initializing the backend...

Initializing provider plugins...
- Finding kreuzwerker/docker versions matching "~> 3.0.1"...
- Installing kreuzwerker/docker v3.0.2...
- Installed kreuzwerker/docker v3.0.2 (self-signed, key ID BD080C4571C6104C)

Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
derek@liuyuanengdeMBP learn-terraform-docker-container % terraform apply

Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
+ create

Terraform will perform the following actions:

# docker_container.nginx will be created
+ resource "docker_container" "nginx" {
+ attach = false
+ bridge = (known after apply)
+ command = (known after apply)
+ container_logs = (known after apply)
+ container_read_refresh_timeout_milliseconds = 15000
+ entrypoint = (known after apply)
+ env = (known after apply)
+ exit_code = (known after apply)
+ hostname = (known after apply)
+ id = (known after apply)
+ image = (known after apply)
+ init = (known after apply)
+ ipc_mode = (known after apply)
+ log_driver = (known after apply)
+ logs = false
+ must_run = true
+ name = "tutorial"
+ network_data = (known after apply)
+ read_only = false
+ remove_volumes = true
+ restart = "no"
+ rm = false
+ runtime = (known after apply)
+ security_opts = (known after apply)
+ shm_size = (known after apply)
+ start = true
+ stdin_open = false
+ stop_signal = (known after apply)
+ stop_timeout = (known after apply)
+ tty = false
+ wait = false
+ wait_timeout = 60

+ ports {
+ external = 8000
+ internal = 80
+ ip = "0.0.0.0"
+ protocol = "tcp"
}
}

# docker_image.nginx will be created
+ resource "docker_image" "nginx" {
+ id = (known after apply)
+ image_id = (known after apply)
+ keep_locally = false
+ name = "nginx"
+ repo_digest = (known after apply)
}

Plan: 2 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.

Enter a value: yes

docker_image.nginx: Creating...
docker_image.nginx: Still creating... [10s elapsed]
docker_image.nginx: Still creating... [20s elapsed]
docker_image.nginx: Creation complete after 22s [id=sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9nginx]
docker_container.nginx: Creating...
docker_container.nginx: Creation complete after 4s [id=09cdec48c9ceb8ada30d02a8e2a8b0a69e546af9187d5befef6ba0088da7623e]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
在原本的資料夾產生 terraform.tfstate 狀態檔
{
"version": 4,
"terraform_version": "1.6.6",
"serial": 3,
"lineage": "45c004aa-6b2c-aab9-4986-7d580e85c33f",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "docker_container",
"name": "nginx",
"provider": "provider[\"registry.terraform.io/kreuzwerker/docker\"]",
"instances": [
{
"schema_version": 2,
"attributes": {
"attach": false,
"bridge": "",
"capabilities": [],
"cgroupns_mode": null,
"command": [
"nginx",
"-g",
"daemon off;"
],
"container_logs": null,
"container_read_refresh_timeout_milliseconds": 15000,
"cpu_set": "",
"cpu_shares": 0,
"destroy_grace_seconds": null,
"devices": [],
"dns": null,
"dns_opts": null,
"dns_search": null,
"domainname": "",
"entrypoint": [
"/docker-entrypoint.sh"
],
"env": [],
"exit_code": null,
"gpus": null,
"group_add": null,
"healthcheck": null,
"host": [],
"hostname": "09cdec48c9ce",
"id": "09cdec48c9ceb8ada30d02a8e2a8b0a69e546af9187d5befef6ba0088da7623e",
"image": "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9",
"init": false,
"ipc_mode": "private",
"labels": [],
"log_driver": "json-file",
"log_opts": null,
"logs": false,
"max_retry_count": 0,
"memory": 0,
"memory_swap": 0,
"mounts": [],
"must_run": true,
"name": "tutorial",
"network_data": [
{
"gateway": "172.17.0.1",
"global_ipv6_address": "",
"global_ipv6_prefix_length": 0,
"ip_address": "172.17.0.2",
"ip_prefix_length": 16,
"ipv6_gateway": "",
"mac_address": "02:42:ac:11:00:02",
"network_name": "bridge"
}
],
"network_mode": "default",
"networks_advanced": [],
"pid_mode": "",
"ports": [
{
"external": 8000,
"internal": 80,
"ip": "0.0.0.0",
"protocol": "tcp"
}
],
"privileged": false,
"publish_all_ports": false,
"read_only": false,
"remove_volumes": true,
"restart": "no",
"rm": false,
"runtime": "runc",
"security_opts": [],
"shm_size": 64,
"start": true,
"stdin_open": false,
"stop_signal": "SIGQUIT",
"stop_timeout": 0,
"storage_opts": null,
"sysctls": null,
"tmpfs": null,
"tty": false,
"ulimit": [],
"upload": [],
"user": "",
"userns_mode": "",
"volumes": [],
"wait": false,
"wait_timeout": 60,
"working_dir": ""
},
"sensitive_attributes": [],
"private": "eyJzY2hlbWFfdmVyc2lvbiI6IjIifQ==",
"dependencies": [
"docker_image.nginx"
]
}
]
},
{
"mode": "managed",
"type": "docker_image",
"name": "nginx",
"provider": "provider[\"registry.terraform.io/kreuzwerker/docker\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"build": [],
"force_remove": null,
"id": "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9nginx",
"image_id": "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9",
"keep_locally": false,
"name": "nginx",
"platform": null,
"pull_triggers": null,
"repo_digest": "nginx@sha256:2bdc49f2f8ae8d8dc50ed00f2ee56d00385c6f8bc8a8b320d0a294d9e3b49026",
"triggers": null
},
"sensitive_attributes": [],
"private": "bnVsbA=="
}
]
}
],
"check_results": null
}
docker ps
#查看 docker 狀態
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
09cdec48c9ce d453dd892d93 "/docker-entrypoint.…" 13 minutes ago Up 13 minutes 0.0.0.0:8000->80/tcp tutorial
terraform destroy
docker_image.nginx: Refreshing state... [id=sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9nginx]
docker_container.nginx: Refreshing state... [id=09cdec48c9ceb8ada30d02a8e2a8b0a69e546af9187d5befef6ba0088da7623e]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
- destroy

Terraform will perform the following actions:

# docker_container.nginx will be destroyed
- resource "docker_container" "nginx" {
- attach = false -> null
- command = [
- "nginx",
- "-g",
- "daemon off;",
] -> null
- container_read_refresh_timeout_milliseconds = 15000 -> null
- cpu_shares = 0 -> null
- dns = [] -> null
- dns_opts = [] -> null
- dns_search = [] -> null
- entrypoint = [
- "/docker-entrypoint.sh",
] -> null
- env = [] -> null
- group_add = [] -> null
- hostname = "09cdec48c9ce" -> null
- id = "09cdec48c9ceb8ada30d02a8e2a8b0a69e546af9187d5befef6ba0088da7623e" -> null
- image = "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9" -> null
- init = false -> null
- ipc_mode = "private" -> null
- log_driver = "json-file" -> null
- log_opts = {} -> null
- logs = false -> null
- max_retry_count = 0 -> null
- memory = 0 -> null
- memory_swap = 0 -> null
- must_run = true -> null
- name = "tutorial" -> null
- network_data = [
- {
- gateway = "172.17.0.1"
- global_ipv6_address = ""
- global_ipv6_prefix_length = 0
- ip_address = "172.17.0.2"
- ip_prefix_length = 16
- ipv6_gateway = ""
- mac_address = "02:42:ac:11:00:02"
- network_name = "bridge"
},
] -> null
- network_mode = "default" -> null
- privileged = false -> null
- publish_all_ports = false -> null
- read_only = false -> null
- remove_volumes = true -> null
- restart = "no" -> null
- rm = false -> null
- runtime = "runc" -> null
- security_opts = [] -> null
- shm_size = 64 -> null
- start = true -> null
- stdin_open = false -> null
- stop_signal = "SIGQUIT" -> null
- stop_timeout = 0 -> null
- storage_opts = {} -> null
- sysctls = {} -> null
- tmpfs = {} -> null
- tty = false -> null
- wait = false -> null
- wait_timeout = 60 -> null

- ports {
- external = 8000 -> null
- internal = 80 -> null
- ip = "0.0.0.0" -> null
- protocol = "tcp" -> null
}
}

# docker_image.nginx will be destroyed
- resource "docker_image" "nginx" {
- id = "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9nginx" -> null
- image_id = "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9" -> null
- keep_locally = false -> null
- name = "nginx" -> null
- repo_digest = "nginx@sha256:2bdc49f2f8ae8d8dc50ed00f2ee56d00385c6f8bc8a8b320d0a294d9e3b49026" -> null
}

Plan: 0 to add, 0 to change, 2 to destroy.

Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.

Enter a value: yes

docker_container.nginx: Destroying... [id=09cdec48c9ceb8ada30d02a8e2a8b0a69e546af9187d5befef6ba0088da7623e]
docker_container.nginx: Destruction complete after 0s
docker_image.nginx: Destroying... [id=sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9nginx]
docker_image.nginx: Destruction complete after 0s
執行完會產生 terraform.tfstate.backup 檔案
{
"version": 4,
"terraform_version": "1.6.6",
"serial": 3,
"lineage": "45c004aa-6b2c-aab9-4986-7d580e85c33f",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "docker_container",
"name": "nginx",
"provider": "provider[\"registry.terraform.io/kreuzwerker/docker\"]",
"instances": [
{
"schema_version": 2,
"attributes": {
"attach": false,
"bridge": "",
"capabilities": [],
"cgroupns_mode": null,
"command": [
"nginx",
"-g",
"daemon off;"
],
"container_logs": null,
"container_read_refresh_timeout_milliseconds": 15000,
"cpu_set": "",
"cpu_shares": 0,
"destroy_grace_seconds": null,
"devices": [],
"dns": null,
"dns_opts": null,
"dns_search": null,
"domainname": "",
"entrypoint": [
"/docker-entrypoint.sh"
],
"env": [],
"exit_code": null,
"gpus": null,
"group_add": null,
"healthcheck": null,
"host": [],
"hostname": "09cdec48c9ce",
"id": "09cdec48c9ceb8ada30d02a8e2a8b0a69e546af9187d5befef6ba0088da7623e",
"image": "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9",
"init": false,
"ipc_mode": "private",
"labels": [],
"log_driver": "json-file",
"log_opts": null,
"logs": false,
"max_retry_count": 0,
"memory": 0,
"memory_swap": 0,
"mounts": [],
"must_run": true,
"name": "tutorial",
"network_data": [
{
"gateway": "172.17.0.1",
"global_ipv6_address": "",
"global_ipv6_prefix_length": 0,
"ip_address": "172.17.0.2",
"ip_prefix_length": 16,
"ipv6_gateway": "",
"mac_address": "02:42:ac:11:00:02",
"network_name": "bridge"
}
],
"network_mode": "default",
"networks_advanced": [],
"pid_mode": "",
"ports": [
{
"external": 8000,
"internal": 80,
"ip": "0.0.0.0",
"protocol": "tcp"
}
],
"privileged": false,
"publish_all_ports": false,
"read_only": false,
"remove_volumes": true,
"restart": "no",
"rm": false,
"runtime": "runc",
"security_opts": [],
"shm_size": 64,
"start": true,
"stdin_open": false,
"stop_signal": "SIGQUIT",
"stop_timeout": 0,
"storage_opts": null,
"sysctls": null,
"tmpfs": null,
"tty": false,
"ulimit": [],
"upload": [],
"user": "",
"userns_mode": "",
"volumes": [],
"wait": false,
"wait_timeout": 60,
"working_dir": ""
},
"sensitive_attributes": [],
"private": "eyJzY2hlbWFfdmVyc2lvbiI6IjIifQ==",
"dependencies": [
"docker_image.nginx"
]
}
]
},
{
"mode": "managed",
"type": "docker_image",
"name": "nginx",
"provider": "provider[\"registry.terraform.io/kreuzwerker/docker\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"build": [],
"force_remove": null,
"id": "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9nginx",
"image_id": "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9",
"keep_locally": false,
"name": "nginx",
"platform": null,
"pull_triggers": null,
"repo_digest": "nginx@sha256:2bdc49f2f8ae8d8dc50ed00f2ee56d00385c6f8bc8a8b320d0a294d9e3b49026",
"triggers": null
},
"sensitive_attributes": [],
"private": "bnVsbA=="
}
]
}
],
"check_results": null
}